/*
    Speedbump aka Project Kimbula
    Copyright (C) 2010  Ping Shin Ching

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see http://www.gnu.org/licenses.

	Ping Shin Ching
	righteous.ninja@gmail.com OR ping_sc@hotmail.com
	More information at http://www.tidytutorials.com/p/speedbump.html
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "init.h"
#include "helpers.h"

const char* InitParameters::zerostring ="0\0";

/*************************************************************************
 * Read and decode an Init file. The data will be over-written by 
 * subsequent calls
 *************************************************************************/
int InitParameters::ReadInitFile(const char* filename){
	
	char line[INITPARAM_STRING*2];
	int labelsize;
	char *pequals, *pend;
	InitParams * tmpparam;

	numberofsections=0;
	sectionName = 0;
	params = 0;
	
	InitParameters* currentparent = this;

	FILE *fp = fopen(filename, "r");
	if(!fp){
		return -1;
	}
	else{
		while(!feof(fp)){
			memset(line, '\0', INITPARAM_STRING*2);
			fgets(line, INITPARAM_STRING*2, fp);
			if(line[0]!='#'){
				if((pequals=strchr(line, '='))!=0){
					tmpparam = (InitParams*)malloc(sizeof(InitParams));

					tmpparam->tag=(char*)calloc((pequals-line+1), sizeof(char));
					tmpparam->value=(char*)calloc((strlen(pequals)+1),sizeof(char));

					memcpy(tmpparam->value, pequals+1, strlen(pequals)+1);
					memcpy(tmpparam->tag, line, pequals-line);
				
					initTrim(tmpparam->value);

					ntarrayadd((void***)&(currentparent->params), sizeof(InitParams*), tmpparam, sizeof(*tmpparam));
					free(tmpparam);
				}
				else if((pequals=strchr(line, '['))!=0 && (pend=strchr(line, ']'))!=0){
					if((labelsize=pend-pequals-1)>0){
						currentparent = new InitParameters();
						currentparent->params = 0;
						currentparent->sectionName = (char*)calloc((labelsize+1), sizeof(char));
						memcpy(currentparent->sectionName, pequals+1, labelsize);
						sections[numberofsections]=currentparent;
						numberofsections++;
					}
					else{
						continue;
					}
					
				}
			}
		}
		fclose(fp);
	}
	return 0;
}


/*************************************************************************
 * Get a parameter
 *************************************************************************/
InitParameters::InitParameters(){
	numberofsections = 0;
	sectionName = 0;		
}

/*************************************************************************
 * Get a parameter
 *************************************************************************/
InitParameters::~InitParameters(){
	int i;
	if(params){
		for(i = 0 ; params[i]!=0 ; i++ ){
			free(params[i]->tag);
			free(params[i]->value);
		}
		ntarraydestroy((void***)&params);
	}
	if(sectionName){
		free(sectionName);
	}
	for(i = 0 ; i < numberofsections ; i++){
		delete sections[i];
	}
}


/*************************************************************************
 * Get a parameter
 *************************************************************************/
const char* InitParameters::GetInitParameter(const char* tag){
	for(int i = 0 ; params!=0 && params[i]!=0 ; i++ ){
		if ( strcmp(params[i]->tag, tag) == 0 ){
			 return params[i]->value;
		}
	}
	printf("INIT: Couldn't find tag %s\n", tag);
	return 0;
}


/*************************************************************************
 * Display all the parameters to stdout
 *************************************************************************/
void* InitParameters::DisplayInitParameters(){
	int i;
	for(i = 0 ; params!=0 && params[i]!=0 ; i++ ){
		printf("%s:%s\n",params[i]->tag, params[i]->value);
	}
	for(i = 0 ; i < numberofsections ; i++){
		printf("[%s]\n", sections[i]->sectionName);
		sections[i]->DisplayInitParameters();
	}
	return 0;
}

InitParameters* InitParameters::GetSectionByName(char* sectionname){
	for(int i = 0 ; i < numberofsections ; i++ ){
		if ( strcmp(sections[i]->sectionName, sectionname) == 0 ){
			 return sections[i];
		}
	}
	//printf("INIT: Couldn't find tag %s\n", tag);
	return 0;
}
InitParameters* InitParameters::GetSectionByIndex(int index){
	if(index<numberofsections)
		return sections[index];
	else
		return 0;
}

/*************************************************************************
 * trim()
 *************************************************************************/
void InitParameters::initTrim(char* in){
	int i;
	char tempvalue[INITPARAM_STRING];
	char* p;
	strcpy(tempvalue, in);
	for(i = 0 ; i < sizeof(totrim) ; i++){
		while((p=strchr(tempvalue, totrim[i])) != 0 && p - tempvalue == 0)
			memmove(tempvalue, tempvalue+1, sizeof(tempvalue)-1);
		while(strlen(tempvalue)>0 && tempvalue[strlen(tempvalue)-1] == totrim[i])
			tempvalue[strlen(tempvalue)-1] ='\0';
	}
	strcpy(in, tempvalue);
}


/*************************************************************************
 * static 'trim' characters
 *************************************************************************/
char InitParameters::totrim[] = {'\t','\n','\v','\f','\r'};
